package com.tanhua.server.serivce;

import com.tanhua.commons.template.HuanXinTemplate;
import com.tanhua.domain.db.Question;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.UserLocation;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.QuestionApi;
import com.tanhua.dubbo.api.mongo.*;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

/**
 * 业务类，封装业务操作，专门给控制器使用
 */
@Service
public class TodayBestService {

    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private RecommendUserApi recommendUserApi;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    private final String TANHUAKEY = "TANHUA_KEY_";

    /**
     * 接口名称：今日佳人
     */
    public ResponseEntity<Object> queryTodayBest() {
        //1. 获取当前登陆用户
        Long userId = UserHolder.getUserId();

        //2. 根据当前登陆用户，调用Api接口，查询今日佳人
        // db.recommend_user.find({userId:20}).sort({score:-1}).limit(1)
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setRecommendUserId(2L);
            recommendUser.setScore(80D);
        }

        //3. 通过定义的TodayBestVo对象，封装返回的数据
        //3.1 创建返回结果
        TodayBestVo todayBestVo = new TodayBestVo();
        //3.2 根据推荐的用户id查询用户信息（今日佳人）
        UserInfo userInfo = userInfoApi.findById(recommendUser.getRecommendUserId());
        if (userInfo != null) {
            //3.3 封装用户信息
            BeanUtils.copyProperties(userInfo, todayBestVo);
            //3.4 设置tags
            if (userInfo.getTags() != null) {
                todayBestVo.setTags(userInfo.getTags().split(","));
            }
            //3.4 设置缘分值（调用Api查询的结果）
            todayBestVo.setFateValue(recommendUser.getScore().longValue());
        }
        //4. 把封装好的TodayBestVo设置到响应体中，返回给前端
        return ResponseEntity.ok(todayBestVo);
    }

    /**
     * 接口名称：推荐朋友 (首页推荐)
     */
    public ResponseEntity<Object> queryRecommendation(RecommendQueryVo vo) {
        //1. 获取当前登陆用户
        Long userId = UserHolder.getUserId();

        //2. 根据当前登陆用户，调用Api接口，分页查询推荐用户
        PageResult pageResult =
                recommendUserApi.queryRecommendation(userId,vo.getPage(),vo.getPagesize());
        //3. 获取查询到的数据
        List<RecommendUser> recommendUserList = (List<RecommendUser>) pageResult.getItems();
        if (recommendUserList == null || recommendUserList.size() == 0) {
            // 如果查询为空，推荐用户默认就是id=5-10
            recommendUserList = new ArrayList<>();
            for (Integer i = 5; i < 10; i++) {
                RecommendUser ru = new RecommendUser();
                ru.setRecommendUserId(i.longValue());
                ru.setScore(70D+i);
                recommendUserList.add(ru);
            }
        }
        //4. 封装TodayBestVo集合对象
        //4.1 创建集合
        List<TodayBestVo> result = new ArrayList<>();
        //4.2 转换：把查询到的recommendUserList数据，封装到todayBestVo
        for (RecommendUser recommendUser : recommendUserList) {
            TodayBestVo todayBestVo = new TodayBestVo();
            UserInfo userInfo = userInfoApi.findById(recommendUser.getRecommendUserId());
            if (userInfo != null) {
                //封装用户信息
                BeanUtils.copyProperties(userInfo, todayBestVo);
                //设置tags
                if (userInfo.getTags() != null) {
                    todayBestVo.setTags(userInfo.getTags().split(","));
                }
                //设置缘分值（调用Api查询的结果）
                todayBestVo.setFateValue(recommendUser.getScore().longValue());

                //把封装好的vo对象，添加到集合
                result.add(todayBestVo);
            }
        }

        //4.3 把封装好的vo设置到pageResult中
        pageResult.setItems(result);

        //4. 把封装好的TodayBestVo设置到响应体中，返回给前端
        return ResponseEntity.ok(pageResult);
    }

    /**
     *  接口名称：佳人信息 （首页点击某一个推荐用户，查看明细）
     */
    public ResponseEntity<Object> queryPersonalInfo(Long recommendUserId) {
        //1. 获取登陆用户id
        Long userId = UserHolder.getUserId();

        //2. 查询推荐佳人用户
        UserInfo userInfo = userInfoApi.findById(recommendUserId);

        //3. 创建返回的对象
        TodayBestVo vo = new TodayBestVo();
        BeanUtils.copyProperties(userInfo,vo);
        if (userInfo.getTags() != null) {
            vo.setTags(userInfo.getTags().split(","));
        }

        //4. 查询某一个用户（20）的缘分值
        //db.recommend_user.find({userId:20,recommendUserId:4})
        Long score = recommendUserApi.queryScore(userId,recommendUserId);
        vo.setFateValue(score);
        return ResponseEntity.ok(vo);
    }

    @Autowired
    private QuestionApi questionApi;
    /**
     * 接口名称：查询陌生人问题
     */
    public ResponseEntity<Object> strangerQuestions(Long userId) {
        // 根据用户id查询tb_question表
        Question question = questionApi.findByUserId(userId);
        // 获取陌生人问题，如果为空给一个默认值
        String txt = question!=null ? question.getTxt() : "我们做一个朋友~";
        return ResponseEntity.ok(txt);
    }

    @Reference
    private UserLocationApi userLocationApi;
    /**
     * 接口名称：搜附近
     */
    public ResponseEntity<Object> searchNear(String gender, Long distance) {
        //1. 获取用户id
        Long userId = UserHolder.getUserId();

        //2. 调用api查询附近人
        // 为什么不能返回UserLocation：因为其中的GeoJsonPoint对象没有实现序列化接口
        // 所以，需要定义UserLocationVo并返回此对象
        List<UserLocationVo> locationList = userLocationApi.searchNear(userId,distance);

        //3. 返回结果
        List<NearUserVo> voList = new ArrayList<>();

        //4. 封装voList返回结果
        if (locationList != null && locationList.size()>0) {
            for (UserLocationVo userLocationVo : locationList) {
                // 搜附近：不能包含自己
                if (userLocationVo.getUserId() == userId) {
                    continue;
                }

                // 搜附件： 根据gender筛选
                UserInfo userInfo = userInfoApi.findById(userLocationVo.getUserId());
                if (userInfo != null) {
                    if (!gender.equals(userInfo.getGender())) {
                        continue;
                    }

                    // 满足条件，返回
                    NearUserVo nearUserVo = new NearUserVo();
                    nearUserVo.setUserId(userInfo.getId());
                    nearUserVo.setAvatar(userInfo.getAvatar());
                    nearUserVo.setNickname(userInfo.getNickname());
                    voList.add(nearUserVo);
                }
            }
        }

        return ResponseEntity.ok(voList);
    }

    @Reference
    private UserLikeApi userLikeApi;
    @Reference
    private UserUnLikeApi userUnLikeApi;

    /**
     * 接口名称：探花-左滑右滑（显示列表）
     */
    public ResponseEntity<Object> queryTanhuaList() {
        // 1. 获取用户id
        Long userId = UserHolder.getUserId();

        // 2. 获取用户的性别，可以进行推荐
        UserInfo userInfo = userInfoApi.findById(userId);
        String gender = userInfo.getGender(); // 性别

        // 2.1 通过性别筛选出用户对象的群体
        // 3.2 通过推荐用户先筛选出数据
        List<UserInfo> userInfoList = new ArrayList<>();
        List<RecommendUser> recommendUserList = recommendUserApi.findById(userId);
        if(recommendUserList == null || recommendUserList.size() == 0) {
            // 3。3 如果为空，就默认从用户表中筛选出来给用户
            userInfoList = userInfoApi.findByGender(gender);
        }else {
            // 遍历得到推荐数据
            for (RecommendUser recommendUser : recommendUserList) {
                Long recommendUserId = recommendUser.getRecommendUserId();
                UserInfo info = userInfoApi.findById(recommendUserId);
                if(info.getGender().equals(gender)) continue;
                userInfoList.add(info);
            }

            // 再判断下，筛选完性别后，是否有数据，如果没有或者小于5,还是从用户表中获取
            if(userInfoList == null || userInfoList.size() < 5) {
                userInfoList = userInfoApi.findByGender(gender);
            }
        }

        // 3. 在得到群体后，再次进行筛选
        // 3.1 创建返回的vo对象集合
        List<TanhuaVo> tanhuaVoList = new ArrayList<>();
        for (UserInfo info : userInfoList) {
            TanhuaVo vo = new TanhuaVo();
            if(info != null) {
                // 3.2 筛选喜欢表中，是否存在
                boolean exitLove = userLikeApi.exitLove(userId, info.getId());
                if(exitLove) continue;

                // 3.3 筛选不喜欢表中，是否存在
                boolean exitUnLove = userUnLikeApi.exitLove(userId, info.getId());
                if(exitLove) continue;

                BeanUtils.copyProperties(info, vo);
                if(info.getTags() != null ) vo.setTags(info.getTags().split(","));

                tanhuaVoList.add(vo);
            }
        }

        return ResponseEntity.ok(tanhuaVoList);
    }

    @Reference
    private FriendApi friendApi;

    /**
     * 接口名称：探花-喜欢
     */
    public ResponseEntity<Object> addLove(Long likeId) {
        // 1. 获取用户id
        Long userId = UserHolder.getUserId();

        // 1.2 判断是否超出限额
        boolean check = checkTanhua(userId);
        if(!check) {
            return ResponseEntity.status(500).body(ErrorResult.tanhuaNumError());
        }

        // 2. 判断likeId是否喜欢过当前用户
        boolean flag = userLikeApi.exitLove(likeId, userId);
        // 3. 再判断当前用户是否喜欢过likeId
        boolean exitLove = userLikeApi.exitLove(userId, likeId);
        // 3.1 首先判断她是否喜欢过我
        if(flag) {
            // 如果我的喜欢没有喜欢她就添加
            if(!exitLove) {
                userLikeApi.save(userId, likeId);
            }
            // 如果他也喜欢我，那自动配对成为好友
            friendApi.save(userId, likeId);

            // --> 增加，添加环信用户
            huanXinTemplate.contactUsers(userId, likeId);
        } else {
            // 这里就是她不喜欢，我就判断是否需要添加
            if(!exitLove) {
                // 如果他不喜欢我, 而且没有查到我喜欢过了，我就在我的喜欢添加我的喜欢
                userLikeApi.save(userId, likeId);
            }
        }
        return ResponseEntity.ok(null);
    }

    /**
     * 接口名称：探花-不喜欢
     */
    public ResponseEntity<Object> addUnLove(Long unlikeId) {
        // 1. 获取用户id
        Long userId = UserHolder.getUserId();

        // 1.2 判断是否超出限额
        boolean check = checkTanhua(userId);
        if(!check) {
            return ResponseEntity.status(500).body(ErrorResult.tanhuaNumError());
        }

        // 2. 判断当前用户是否喜欢过likeId
        boolean exitLove = userLikeApi.exitLove(userId, unlikeId);

        // 3. 如果没有，就添加到不喜欢表中，如果有就删除原来的喜欢表中
        if(exitLove) {
            // 如果他不喜欢我, 而且没有查到我喜欢过了，我就在我的喜欢添加我的喜欢
            userLikeApi.delete(userId.intValue(), unlikeId);
        }

        // 4. 判断是否存在了不喜欢表中
        if(!userUnLikeApi.exitLove(userId, unlikeId)) {
            userUnLikeApi.save(userId, unlikeId);
        }

        return ResponseEntity.ok(null);
    }

    // 判断每日判断限额次数
    private boolean checkTanhua(Long userId){
        // 1 增加次数限制
        String key = TANHUAKEY + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "_" + userId;
        if(!redisTemplate.hasKey(key)){
            redisTemplate.opsForValue().set(key, "1", Duration.ofDays(1));
    }

        String str = redisTemplate.opsForValue().get(key);
        // 2. 限额100次
        int num = Integer.parseInt(str);
        int upNum = 10; // 上限数量
        // 3. 判断是否为会员状态
        UserInfo userInfo = userInfoApi.findById(userId);
        if(userInfo.getVipId() == 1) {
            upNum = 10000000;
        }
        // 4. 判断是否上限
        if(num >= upNum) {
            return false;
        }
        num += 1;
        redisTemplate.opsForValue().set(key, num + "");
        return true;
    }
}
